#include "Screen.h"

HWND Screen::hwnd;


HWND Screen::getHWnd() {
	return hwnd;
}

void Screen::setBufferTo(BYTE color) {

	DDBLTFX ddbltfx;
	ZeroMemory(&ddbltfx,sizeof(ddbltfx));
	ddbltfx.dwSize = sizeof(ddbltfx);
	ddbltfx.dwFillColor = color;
	lpDDSBack->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&ddbltfx);
}


void Screen::drawText(long x, long y, char *text) {
//	lpDDSBack->DrawText(x, y, text, false);
}

int Screen::init(HWND hwnd) {

	// GET DIRECT DRAW OBJECT

	// Create the DDraw object. This is used to access anything
	// DirectDraw does.
	if (FAILED( DirectDrawCreateEx( NULL, ( LPVOID* )&dDrawObj, IID_IDirectDraw7, NULL ) ) )
		return FALSE;

	// SET DISPLAY MODE

	// Get exclusive mode. Be sure to allow people to press
	// Alt-Ctrl-Del ( DDSCL_ALLOWREBOOT ).

	if ( FAILED( dDrawObj->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN) ) )
	   return FALSE;

	Screen::hwnd=hwnd;
	
	return 0;

}

int Screen::setMode(WORD width, WORD height, BYTE bit_depth) {

	int ddrval;
	
	// Set the display mode
	if ( FAILED( dDrawObj->SetDisplayMode( width, height, bit_depth, 0, 0 ) ) )
	   return FALSE;

	// CREATE PRIMARY SURFACE

	// Create the primary surface with 1 back buffer. Make it
	// the height and width of the screen.

	// First, zero the memory used by the ddsd structure.
	// If you don't do this, it may have some random data that
	// might mess up CreateSurface().
	ZeroMemory( &ddsd, sizeof( ddsd ) );
	ddsd.dwSize = sizeof( ddsd );

	// DDSD_CAPS makes CreateSurface() check the
	// ddsd.ddsCaps.dwCaps value. DDS_BACKBUFFERCOUNT makes it
	// check the ddsd.dwBackBufferCount value.
	ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

	// Make it the primary surface that can be flipped.
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;

	// Give it one back buffer.
	ddsd.dwBackBufferCount = 1;

	// Create the primary surface using the description in ddsd.
	if ( FAILED( dDrawObj->CreateSurface( &ddsd, &lpDDSPrimary, NULL ) ) )
	   return FALSE;

	// CREATE BACK BUFFER
    // Get the pointer to the back buffer
    ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
    ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
    if( ddrval != DD_OK ) {
        lpDDSPrimary->Release();
        dDrawObj->Release();
        return(false);
    }

	Screen::width=width;
	Screen::height=height;
	return 0;
}

int Screen::putBitmap(SDWORD x, SDWORD y, Bitmap& bitmap) {

	RECT rcFrom;
	rcFrom.left = 0;
	rcFrom.top = 0;
	rcFrom.right = bitmap.width;
	rcFrom.bottom = bitmap.height;


	if ( FAILED( lpDDSBack->BltFast( x, y, bitmap.surface, &rcFrom, DDBLTFAST_SRCCOLORKEY  | DDBLTFAST_WAIT ) ) )
	   return FALSE; 

	return 0;
}

int Screen::putBitmapRect(SDWORD x, SDWORD y, RECT& rect, Bitmap& bitmap) {

	if ( FAILED( lpDDSBack->BltFast( x, y, bitmap.surface, &rect, DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT ) ) )
	   return FALSE; 

	return 0;
}


void Screen::dumpBuffer() {
	int ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );
	if (ddrval==DDERR_SURFACELOST)
		dDrawObj->RestoreAllSurfaces();
}

int Screen::setPal(Pal& paleta) {

	IDirectDrawPalette* DDpal;
	PALETTEENTRY pEntry[256];

	for (WORD t=0; t<256; t++) {
		pEntry[t].peRed=paleta.R[t];
		pEntry[t].peGreen=paleta.G[t];
		pEntry[t].peBlue=paleta.B[t];
	}

	if (dDrawObj->CreatePalette(DDPCAPS_8BIT, pEntry, &DDpal, NULL) != DD_OK)
		return NULL;

	if (DDpal)
		lpDDSPrimary->SetPalette(DDpal); // this sets the palette for the primary surface



	return 0;
}


LPDIRECTDRAWSURFACE7 Screen::lpDDSPrimary=NULL;
LPDIRECTDRAWSURFACE7 Screen::lpDDSBack=NULL;
DDSURFACEDESC2 Screen::ddsd;
DDSCAPS2 Screen::ddscaps;
LPDIRECTDRAW7 Screen::dDrawObj=NULL;
WORD Screen::width=0;
WORD Screen::height=0;

